﻿namespace Raven
{
    public static class RavenFeature
    {
        //returns a value between 0 and 1 based on the bot's health. The better
        //the health, the higher the rating
        public static Fix Health(RavenBot pBot)
        {
            return pBot.Health() * 1 / pBot.MaxHealth();
        }

        //returns a value between 0 and 1 based on the bot's closeness to the 
        //given item. the further the item, the higher the rating. If there is no
        //item of the given type present in the game world at the time this method
        //is called the value returned is 1
        public static Fix DistanceToItem(RavenBot pBot, EntityType ItemType)
        {
            //determine the distance to the closest instance of the item type
            Fix DistanceToItem = pBot.GetPathPlanner().GetCostToClosestItem(ItemType);

            //if the previous method returns a negative value then there is no item of
            //the specified type present in the game world at this time.
            if (DistanceToItem < 0) return 1;

            //these values represent cutoffs. Any distance over MaxDistance results in
            //a value of 0, and value below MinDistance results in a value of 1
            Fix MaxDistance = 500;
            Fix MinDistance = 50;

            DistanceToItem = FixMath.Clamp(DistanceToItem, MinDistance, MaxDistance);

            return DistanceToItem / MaxDistance;
        }

        //returns a value between 0 and 1 based on how much ammo the bot has for
        //the given weapon, and the maximum amount of ammo the bot can carry. The
        //closer the amount carried is to the max amount, the higher the score
        public static Fix IndividualWeaponStrength(RavenBot pBot, WeaponType WeaponType)
        {
            return 0;
        }

        //----------------------- GetMaxRoundsBotCanCarryForWeapon --------------------
        //
        //  helper function to tidy up IndividualWeapon method
        //  returns the maximum rounds of ammo a bot can carry for the given weapon
        //-----------------------------------------------------------------------------
        public static Fix GetMaxRoundsBotCanCarryForWeapon(WeaponType weaponType)
        {
            switch (weaponType)
            {
                case WeaponType.type_rail_gun:

                    return Constants.RailGun_MaxRoundsCarried;

                case WeaponType.type_rocket_launcher:

                    return Constants.RocketLauncher_MaxRoundsCarried;

                case WeaponType.type_shotgun:

                    return Constants.ShotGun_MaxRoundsCarried;

                default:
                    Logger.LogError("trying to calculate  of unknown weapon");
                    return 0;
            } //end switch
        }

        //returns a value between 0 and 1 based on the total amount of ammo the
        //bot is carrying each of the weapons. Each of the three weapons a bot can
        //pick up can contribute a third to the score. In other words, if a bot
        //is carrying a RL and a RG and has max ammo for the RG but only half max
        //for the RL the rating will be 1/3 + 1/6 + 0 = 0.5
        public static Fix TotalWeaponStrength(RavenBot pBot)
        {
            Fix MaxRoundsForShotgun = GetMaxRoundsBotCanCarryForWeapon(WeaponType.type_shotgun);
            Fix MaxRoundsForRailgun = GetMaxRoundsBotCanCarryForWeapon(WeaponType.type_rail_gun);
            Fix MaxRoundsForRocketLauncher = GetMaxRoundsBotCanCarryForWeapon(WeaponType.type_rocket_launcher);
            Fix TotalRoundsCarryable = MaxRoundsForShotgun + MaxRoundsForRailgun + MaxRoundsForRocketLauncher;

            Fix NumSlugs = pBot.GetWeaponSys().GetAmmoRemainingForWeapon(WeaponType.type_rail_gun);
            Fix NumCartridges = pBot.GetWeaponSys().GetAmmoRemainingForWeapon(WeaponType.type_shotgun);
            Fix NumRockets = pBot.GetWeaponSys().GetAmmoRemainingForWeapon(WeaponType.type_rocket_launcher);

            //the value of the tweaker (must be in the range 0-1) indicates how much
            //desirability value is returned even if a bot has not picked up any weapons.
            //(it basically adds in an amount for a bot's persistent weapon -- the blaster)
            Fix Tweaker = Fix.Ratio(1, 10);

            return Tweaker + (1 - Tweaker) * (NumSlugs + NumCartridges + NumRockets) /
                (MaxRoundsForShotgun + MaxRoundsForRailgun + MaxRoundsForRocketLauncher);
        }
    }
}